package org.allrtc.wrap;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.util.Log;

import com.qttaudio.sdk.channel.AudioMode;
import com.qttaudio.sdk.channel.AudioOutput;
import com.qttaudio.sdk.channel.AudioParams;
import com.qttaudio.sdk.channel.AudioQuality;
import com.qttaudio.sdk.channel.ChannelEngine;
import com.qttaudio.sdk.channel.ChannelFactory;
import com.qttaudio.sdk.channel.ChannelObserver;
import com.qttaudio.sdk.channel.ChannelRole;
import com.qttaudio.sdk.channel.LogLevel;
import com.qttaudio.sdk.channel.RtcStat;
import com.qttaudio.sdk.channel.VolumeInfo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import io.agora.rtc.Constants;
import io.agora.rtc.IAudioEffectManager;
import io.agora.rtc.IAudioFrameObserver;
import io.agora.rtc.IMetadataObserver;
import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcChannel;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.internal.EncryptionConfig;
import io.agora.rtc.internal.LastmileProbeConfig;
import io.agora.rtc.live.LiveInjectStreamConfig;
import io.agora.rtc.live.LiveTranscoding;
import io.agora.rtc.mediaio.IVideoSink;
import io.agora.rtc.mediaio.IVideoSource;
import io.agora.rtc.models.ClientRoleOptions;
import io.agora.rtc.models.UserInfo;
import io.agora.rtc.video.AgoraImage;
import io.agora.rtc.video.AgoraVideoFrame;
import io.agora.rtc.video.BeautyOptions;
import io.agora.rtc.video.CameraCapturerConfiguration;
import io.agora.rtc.video.ChannelMediaRelayConfiguration;
import io.agora.rtc.video.VideoCanvas;
import io.agora.rtc.video.VideoEncoderConfiguration;
import io.agora.rtc.video.WatermarkOptions;

import static io.agora.rtc.Constants.LOG_FILTER_CRITICAL;
import static io.agora.rtc.Constants.LOG_FILTER_DEBUG;
import static io.agora.rtc.Constants.LOG_FILTER_ERROR;
import static io.agora.rtc.Constants.LOG_FILTER_INFO;
import static io.agora.rtc.Constants.LOG_FILTER_OFF;
import static io.agora.rtc.Constants.LOG_FILTER_WARNING;
import static io.agora.rtc.Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_ERROR;
import static io.agora.rtc.Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_PAUSED;
import static io.agora.rtc.Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_PLAY;
import static io.agora.rtc.Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_STOPPED;

public class QttRtcEngine extends RtcEngine {
    private static final int mAudioVolumeSize = 20;
    private ChannelEngine rtcEngine = null;
    private long my_uid = 0;
    private ChannelRole channelRole = ChannelRole.AUDIENCE;
    private boolean mIsLeaved = true;
    private Context context = null;
    private IRtcEngineEventHandler.RemoteAudioStats remoteAudioStats = new IRtcEngineEventHandler.RemoteAudioStats();
    private IRtcEngineEventHandler.LocalAudioStats localAudioStats = new IRtcEngineEventHandler.LocalAudioStats();
    private IRtcEngineEventHandler iRtcEngineEventHandler = null;
    private IRtcEngineEventHandler.AudioVolumeInfo[] mAudioVolumeInfos = new IRtcEngineEventHandler.AudioVolumeInfo[mAudioVolumeSize];
    private ChannelObserver channelObserver = new ChannelObserver() {

        private IRtcEngineEventHandler.AudioVolumeInfo[] a = new IRtcEngineEventHandler.AudioVolumeInfo[1];

        /**
         * 进入房间成功
         */
        @Override
        public void onJoinSuccess(String roomName, long uid, ChannelRole role, boolean muted, boolean isReconnect) {
            Log.d("qtt_rtc", "onJoinSuccess roomId:" + roomName + "   uid:" + uid + "  role:" + role + "  ");
            my_uid = uid;
            if (!isReconnect)
                iRtcEngineEventHandler.onJoinChannelSuccess(roomName, (int) uid, 0);
            else
                iRtcEngineEventHandler.onRejoinChannelSuccess(roomName, (int) uid, 0);
        }

        /**
         * 进入房间失败
         *
         * @param code
         * @param message
         */
        @Override
        public void onJoinFail(final int code, final String message) {
//            Log.d("qtt_rtc", "onJoinFail " + message);
            //todo 先弄成声网的这个状态返回
            switch (code) {
                case -7: {
                    iRtcEngineEventHandler.onError(Constants.ERR_NOT_SUPPORTED);
                    break;
                }
                case -3: {
                    iRtcEngineEventHandler.onError(Constants.ERR_INVALID_TOKEN);
                    break;
                }
                case -2:
                case -4:
                case -5:
                case -6:
                case -9: {
                    iRtcEngineEventHandler.onError(Constants.ERR_JOIN_CHANNEL_REJECTED);
                    break;
                }
            }
//            iRtcEngineEventHandler.onConnectionStateChanged(Constants.CONNECTION_STATE_FAILED, Constants.CONNECTION_CHANGED_JOIN_FAILED);
        }

        /**
         * 退出房间成功的通知
         */
        @Override
        public void onLeave() {
            iRtcEngineEventHandler.onLeaveChannel(new IRtcEngineEventHandler.RtcStats());
        }

        /**
         * 网络连接中断的通知，SDK会马上回调onWaitReconnecting准备重连
         */
        @Override
        public void onConnectionBreak() {
            iRtcEngineEventHandler.onConnectionInterrupted();
//            iRtcEngineEventHandler.onConnectionStateChanged(Constants.CONNECTION_STATE_DISCONNECTED, Constants.CONNECTION_CHANGED_INTERRUPTED);
        }

        @Override
        public void onConnectionLost() {
            iRtcEngineEventHandler.onConnectionLost();
        }

        @Override
        public void onError(int err, String message) {
            iRtcEngineEventHandler.onError(err);
        }

        @Override
        public void onWarning(int warn,  String message) {
            iRtcEngineEventHandler.onWarning(warn);
        }

        @Override
        public void onOtherJoin(long uid, ChannelRole role, boolean muted) {
            if (role == ChannelRole.TALKER) {
                iRtcEngineEventHandler.onUserJoined((int) uid, 0);
//                iRtcEngineEventHandler.onUserMuteAudio((int) user.getUid(), user.isMuted());
            }
        }

        @Override
        public void onOtherLeave(long uid, ChannelRole role) {
            Log.d("qtt_rtc", "onOtherLeave " + uid);
            //TODO:reason  默认离开原因 0：用户主动离开;
            if (role == ChannelRole.TALKER) //主播退出才通知，QTT是全部都通知
                iRtcEngineEventHandler.onUserOffline((int) uid, Constants.USER_OFFLINE_QUIT);
        }

        /**
         * 音量提示
         * @param volumeInfos
         */
        @Override
        public void onTalking(VolumeInfo[] volumeInfos, int size) {
            if (size < 1)
                return;
            IRtcEngineEventHandler.AudioVolumeInfo[] audioVolumeInfos = new IRtcEngineEventHandler.AudioVolumeInfo[size];
            for (int i = 0; i < size; i++) {
                mAudioVolumeInfos[i].uid = (int) volumeInfos[i].uid;
                mAudioVolumeInfos[i].vad = volumeInfos[i].vad;
                mAudioVolumeInfos[i].volume = volumeInfos[i].volume;
                audioVolumeInfos[i] = mAudioVolumeInfos[i];
            }
            iRtcEngineEventHandler.onAudioVolumeIndication(audioVolumeInfos, 0);
        }

        @Override
        public void onMuteStatusChanged(long uid, boolean muted) {
            if (uid != 0) {
                iRtcEngineEventHandler.onUserMuteAudio((int)uid, muted);
            }
        }

        @Override
        public void onRoleStatusChanged(long uid, ChannelRole role) {
            if (uid != 0) {
                if (role == ChannelRole.TALKER) {
                    iRtcEngineEventHandler.onUserJoined((int)uid, 1);
//                iRtcEngineEventHandler.onUserMuteAudio((int) user.getUid(), user.isMuted());
                } else {
//                iRtcEngineEventHandler.onUserMuteAudio((int) user.getUid(), true);
                    iRtcEngineEventHandler.onUserOffline((int)uid, Constants.USER_OFFLINE_BECOME_AUDIENCE); //用户身份从主播切换为观众（直播模式下）
                }
            } else {
                int nowRole = channelRole.value() + 1;
                if (nowRole == 1)
                    iRtcEngineEventHandler.onClientRoleChanged(2, nowRole);
                else
                    iRtcEngineEventHandler.onClientRoleChanged(1, nowRole);
            }
        }

        @Override
        public void onNetworkStats(long uid, int txQuality, int rxQuality, RtcStat stat) {
            iRtcEngineEventHandler.onNetworkQuality((int)uid, txQuality, rxQuality);
			
            if (uid == 0) {
                //先找两个字段存下数据抛到外包去，上报时确认字段含义
                localAudioStats.sentBitrate = stat.mRttAverage; //rtt是自己与服务器的往返时间，毫秒；sentBitrate是发送比特率，两个并不对应。
                localAudioStats.sentSampleRate = stat.mJitter;
                iRtcEngineEventHandler.onLocalAudioStats(localAudioStats);
            } else {
                remoteAudioStats.audioLossRate = stat.mUpLossRate;
                remoteAudioStats.jitterBufferDelay = stat.mJitter;
                remoteAudioStats.networkTransportDelay = stat.mRttAverage;
                remoteAudioStats.receivedBitrate = stat.hashCode();
                remoteAudioStats.uid = (int) uid;
                iRtcEngineEventHandler.onRemoteAudioStats(remoteAudioStats);
            }

        }

        @Override
        public void onAudioRouteChanged(int route) {

        }

        @Override
        public void onSoundStateChanged(int state) {
            Log.d("qtt_log", "onSoundStateChanged: " + state);
            switch (state) {
                case 0: {
                    iRtcEngineEventHandler.onAudioMixingStateChanged(MEDIA_ENGINE_AUDIO_EVENT_MIXING_PLAY, 0);
                    break;
                }
                case 1: {
                    iRtcEngineEventHandler.onAudioMixingStateChanged(MEDIA_ENGINE_AUDIO_EVENT_MIXING_PAUSED, 0);
                    break;
                }
                case 2: {
                    iRtcEngineEventHandler.onAudioMixingStateChanged(MEDIA_ENGINE_AUDIO_EVENT_MIXING_STOPPED, 0);
                    break;
                }
                case 3: {
                    iRtcEngineEventHandler.onAudioMixingStateChanged(MEDIA_ENGINE_AUDIO_EVENT_MIXING_ERROR, 0);
                    break;
                }
                case 4: {
                    iRtcEngineEventHandler.onAudioMixingFinished();
                    break;
                }
            }
        }

        @Override
        public void onEffectFinished(int effectId) {

        }
    };

    public QttRtcEngine(Context context, String appId, IRtcEngineEventHandler handler) throws Exception {
        this.context = context;
        //todo SetAppLicense
//        ChannelFactory.SetAppLicense("");
        ChannelFactory.SetContext(context);
        ChannelFactory.SetAppkey(appId);
        ChannelFactory.SetLogLevel(LogLevel.LOG_MESSAGE);
        rtcEngine = ChannelFactory.GetChannelInstance();
        if (rtcEngine == null)
            throw new Exception("Qtt初始化失败");
        rtcEngine.setObserver(channelObserver);
        iRtcEngineEventHandler = handler;

        for (int k = 0; k < mAudioVolumeSize; k++) {
            IRtcEngineEventHandler.AudioVolumeInfo tmp = new IRtcEngineEventHandler.AudioVolumeInfo();
            mAudioVolumeInfos[k] = tmp;
        }
    }

    private String copyFile(Context context, String fileName) {
        String result = context.getFilesDir() + "/" + fileName;
        try {
            File file = new File(result);
            if (file.exists()) {
                return result;
            }
            InputStream is = context.getAssets().open(fileName);
            FileOutputStream fos = new FileOutputStream(result);
            byte[] buffer = new byte[4096];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            fos.flush();
            fos.close();
            is.close();
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    //释放的时候，用这个delete方法，不用用RtcEngine.destroy();
    public synchronized void delete() {
        ChannelFactory.Destroy();
        rtcEngine = null;
        context = null;
    }

    @Override
    public int setAudioProfile(int profile, int scenario) {
        AudioQuality quality = AudioQuality.AUDIO_QUALITY_MUSIC_STEREO;
        AudioMode mode = AudioMode.AUDIO_MODE_CALL;

        if (scenario == Constants.AUDIO_SCENARIO_CHATROOM_GAMING || scenario == Constants.AUDIO_SCENARIO_DEFAULT) {
            mode = AudioMode.AUDIO_MODE_CALL; //通话模式
        } else if (scenario == Constants.AUDIO_SCENARIO_CHATROOM_ENTERTAINMENT) {
            mode = AudioMode.AUDIO_MODE_LIVE2;//暂时不使用
        } else if (scenario == Constants.AUDIO_SCENARIO_GAME_STREAMING) {
            mode = AudioMode.AUDIO_MODE_LIVE;//暂时不太建议使用
        } else {
            mode = AudioMode.AUDIO_MODE_MIX;  //上麦通话，下麦媒体
        }

        return rtcEngine.setAudioConfig(quality, mode);
    }

    /**
     * @param fullband
     * @param stereo
     * @param fullBitrate
     * @deprecated
     */
    @Override
    public int setHighQualityAudioParameters(boolean fullband, boolean stereo, boolean fullBitrate) {
        return 0;
    }

    @Override
    public int setClientRole(int var1) {
        channelRole = (var1 == Constants.CLIENT_ROLE_BROADCASTER) ? ChannelRole.TALKER : ChannelRole.AUDIENCE;
//        if (channelRole == ChannelRole.TALKER) {
//            muteLocalAudioStream(false);
//        }
        rtcEngine.changeRole(channelRole);
        return 0;
    }

    @Override
    public int setClientRole(int role, ClientRoleOptions options) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int sendCustomReportMessage(String id, String category, String event, String label, int value) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int joinChannel(String token, String channelName, String optionalInfo, int optionalUid) {
        rtcEngine.setUid(optionalUid);
//        if (isDefaultSpekaer && !hasBluetoothHeadset && !hasWiredHeadset)
//            AudioOutput.routeAudioTo(AudioOutput.SPEAKER);
//        else if (hasBluetoothHeadset) {
//            AudioOutput.routeAudioTo(AudioOutput.BLUETOOTH);
//        } else
//            AudioOutput.routeAudioTo(AudioOutput.HEADPHONE);
        rtcEngine.join(channelName,token);
        mIsLeaved = false;
        return 0;
    }

    @Override
    public int switchChannel(String token, String channelName) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setChannelProfile(int profile) {
        //TODO: 设置频道模式->与默认外放挂钩
//        if (Constants.CHANNEL_PROFILE_COMMUNICATION == profile)
//            isDefaultSpekaer = false;
//        else if (Constants.CHANNEL_PROFILE_LIVE_BROADCASTING == profile)
//            isDefaultSpekaer = true;
//        else
//            isDefaultSpekaer = true;
        return 0;
    }

    @Override
    public int leaveChannel() {
        stopAudioMixing();
        mIsLeaved = true;
        rtcEngine.leave();
        return 0;
    }

    @Override
    public int renewToken(String token) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int registerLocalUserAccount(String appId, String userAccount) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int joinChannelWithUserAccount(String token, String channelName, String userAccount) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int getUserInfoByUserAccount(String userAccount, UserInfo userInfo) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int getUserInfoByUid(int uid, UserInfo userInfo) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int enableWebSdkInteroperability(boolean enabled) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int getConnectionState() {
        //TODO: 没有
        return -1;
    }

    public int enableRemoteSuperResolution(int uid, boolean enable) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int enableAudio() {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int disableAudio() {
        //TODO: 暂时没有
        return -1;
    }

    /**
     * @deprecated
     */
    @Override
    public int pauseAudio() {
        //TODO: 没有
        return -1;
    }

    /**
     * @deprecated
     */
    @Override
    public int resumeAudio() {
        //TODO: 没有
        return -1;
    }

    @Override
    public int enableAudioVolumeIndication(int interval, int smooth, boolean report_vad) {
        rtcEngine.setVolumeDectection(interval);
        return 0;
    }

    /**
     * @param enabled
     * @deprecated
     */
    @Override
    public int enableAudioQualityIndication(boolean enabled) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int enableLocalAudio(boolean enabled) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int muteLocalAudioStream(boolean muted) {
        rtcEngine.mute(0, muted);
        return 0;
    }

    @Override
    public int muteAllRemoteAudioStreams(boolean muted) {
        rtcEngine.muteAllRemote(muted);
        return 0;
    }

    @Override
    public int setDefaultMuteAllRemoteAudioStreams(boolean muted) {
        rtcEngine.muteAllRemote(muted);
        return 0;
    }

    @Override
    public int enableVideo() {
        //TODO: 没有
        return -1;
    }

    @Override
    public int disableVideo() {
        //TODO: 没有
        return -1;
    }

    /**
     * @param profile
     * @param swapWidthAndHeight
     * @deprecated
     */
    @Override
    public int setVideoProfile(int profile, boolean swapWidthAndHeight) {
        //TODO: 没有
        return -1;
    }

    /**
     * @param width
     * @param height
     * @param frameRate
     * @param bitrate
     * @deprecated
     */
    @Override
    public int setVideoProfile(int width, int height, int frameRate, int bitrate) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setVideoEncoderConfiguration(VideoEncoderConfiguration config) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setCameraCapturerConfiguration(CameraCapturerConfiguration config) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setupLocalVideo(VideoCanvas local) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setupRemoteVideo(VideoCanvas remote) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setLocalRenderMode(int mode) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setLocalRenderMode(int i, int i1) {
        return -1;
    }

    @Override
    public int setRemoteRenderMode(int uid, int mode) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setRemoteRenderMode(int i, int i1, int i2) {
        return -1;
    }

    @Override
    public int startPreview() {
        //TODO: 没有
        return -1;
    }

    @Override
    public int stopPreview() {
        //TODO: 没有
        return -1;
    }

    @Override
    public int enableLocalVideo(boolean enabled) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int muteLocalVideoStream(boolean muted) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int muteRemoteVideoStream(int uid, boolean muted) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int muteAllRemoteVideoStreams(boolean muted) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setDefaultMuteAllRemoteVideoStreams(boolean muted) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setBeautyEffectOptions(boolean enabled, BeautyOptions options) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setDefaultAudioRoutetoSpeakerphone(boolean defaultToSpeaker) {
        //TODO: 没有
//        this.isDefaultSpekaer = defaultToSpeaker;
        return 0;
    }

    @Override
    public int muteRemoteAudioStream(int uid, boolean var1) {
        rtcEngine.mute(uid, var1);
        return 0;
    }

    @Override
    public int adjustUserPlaybackSignalVolume(int i, int i1) {
        rtcEngine.adjustUserVolume(i, i1);
        return 0;
    }

    @Override
    public int setEnableSpeakerphone(boolean enabled) {
//        if (enabled) {
//            AudioOutput.routeAudioTo(AudioOutput.SPEAKER);
//        } else {
//            if (hasBluetoothHeadset)
//                AudioOutput.routeAudioTo(AudioOutput.BLUETOOTH);
//            else
//                AudioOutput.routeAudioTo(AudioOutput.HEADPHONE);
//
//        }
//        isDefaultSpekaer = enabled;
//        rtcEngine.setSpeakerOn(enabled);
        rtcEngine.setSpeakerOn(enabled);
        return 0;
    }

    /**
     * 调节录音音量。
     *
     * @param volume 录音信号音量，可在 0~400 范围内进行调节：
     * @return
     */
    @Override
    public int adjustRecordingSignalVolume(int volume) {
        rtcEngine.adjustMicVolume(volume);
        return 0;
    }

    @Override
    public boolean isSpeakerphoneEnabled() {
        return AudioOutput.isSpeaker();
    }

    @Override
    public int enableInEarMonitoring(boolean enabled) {
        return rtcEngine.enableInEarMonitoring(enabled);
    }

    @Override
    public int setInEarMonitoringVolume(int volume) {
        return rtcEngine.setInEarMonitoringVolume(volume);
    }

    /**
     * @deprecated
     */
    @Override
    public int useExternalAudioDevice() {
        //TODO: 没有
        return -1;
    }

    @Override
    public int setLocalVoicePitch(double pitch) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setLocalVoiceEqualization(int bandFrequency, int bandGain) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setLocalVoiceReverb(int reverbKey, int value) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setLocalVoiceChanger(int voiceChanger) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setLocalVoiceReverbPreset(int preset) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setAudioEffectPreset(int preset) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setVoiceBeautifierPreset(int preset) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setAudioEffectParameters(int preset, int param1, int param2) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int enableSoundPositionIndication(boolean enabled) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setRemoteVoicePosition(int uid, double pan, double gain) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int adjustPlaybackSignalVolume(int volume) {
        rtcEngine.adjustPlayVolume(volume);
        return 0;
    }

    /**
     * @param filePath
     * @param loopback
     * @param replace  true：只有本地可以听到混音或替换后的音频流  false：本地和对方都可以听到混音或替换后的音频流
     * @param cycle
     * @return
     */
    @Override
    public int startAudioMixing(String filePath, boolean loopback, boolean replace, int cycle) {
        if (mIsLeaved) {
            Log.e("qtt_mixer", "start audio mix failed as not join channel");
            return -1;
        }
        //开始播放音乐文件及混音。todo: replace 暂时没有
        String fileName = filePath;
        if (filePath.contains("/assets/"))
            fileName = copyFile(context, filePath.substring(8));

        return rtcEngine.playSound(fileName, cycle, !loopback);
    }

    @Override
    public int stopAudioMixing() {
        if (mIsLeaved) {
            Log.e("qtt_mixer", "stop audio mix failed as not join channel");
            return -1;
        }
        return rtcEngine.stopSound();
    }

    /**
     * 调节音乐文件的播放音量
     *
     * @param var1
     * @return
     */
    @Override
    public int adjustAudioMixingVolume(int var1) {
        rtcEngine.setSoundPublishVolume(var1);
        rtcEngine.setSoundPlayoutVolume(var1);
        return 0;
    }


    @Override
    public int adjustAudioMixingPublishVolume(int volume) {
        return rtcEngine.setSoundPublishVolume(volume);
    }

    @Override
    public int getAudioMixingPlayoutVolume() {
        return rtcEngine.getSoundPlayoutVolume();
    }

    @Override
    public int getAudioMixingPublishVolume() {
        return rtcEngine.getSoundPublishVolume();
    }

    @Override
    public int adjustAudioMixingPlayoutVolume(int volume) {
        return rtcEngine.setSoundPlayoutVolume(volume);
    }

    @Override
    public int setLogFile(String var1) {
        ChannelFactory.SetLogFile(var1);
        return 0;
    }

    @Override
    public int setLogFilter(int filter) {
        LogLevel level = LogLevel.LOG_OFF;
        if (filter == LOG_FILTER_OFF) {
            level = LogLevel.LOG_OFF;
        } else if (filter == LOG_FILTER_DEBUG) {
            level = LogLevel.LOG_DEBUG;
        } else if (filter == LOG_FILTER_INFO) {
            level = LogLevel.LOG_MESSAGE;
        } else if (filter == LOG_FILTER_WARNING) {
            level = LogLevel.LOG_WARNING;
        } else if (filter == LOG_FILTER_ERROR) {
            level = LogLevel.LOG_ERROR;
        } else if (filter == LOG_FILTER_CRITICAL) {
            level = LogLevel.LOG_FATAL;
        } else {
            return -1;
        }
        ChannelFactory.SetLogLevel(level);
        return 0;
    }

    @Override
    public int setLogFileSize(int fileSizeInKBytes) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public long getNativeHandle() {
        //TODO: 暂时没有
        return -1;
    }

    /**
     * @param enable
     * @deprecated
     */
    @Override
    public boolean enableHighPerfWifiMode(boolean enable) {
        //TODO: 没有
        return false;
    }

    /**
     * @param monitor
     * @deprecated
     */
    @Override
    public void monitorHeadsetEvent(boolean monitor) {
        //TODO: 没有
    }

    /**
     * @param monitor
     * @deprecated
     */
    @Override
    public void monitorBluetoothHeadsetEvent(boolean monitor) {
        //TODO: 没有
    }

    /**
     * @param enabled
     * @deprecated
     */
    @Override
    public void setPreferHeadset(boolean enabled) {
        //TODO: 没有
    }

    @Override
    public int setParameters(String parameters) {
        //TODO: 没有
        return -1;
    }

    @Override
    public String getParameter(String parameter, String args) {
        //TODO: 没有
        return null;
    }

    @Override
    public int registerMediaMetadataObserver(IMetadataObserver observer, int type) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int startChannelMediaRelay(ChannelMediaRelayConfiguration channelMediaRelayConfiguration) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int stopChannelMediaRelay() {
        //TODO: 没有
        return -1;
    }

    @Override
    public int updateChannelMediaRelay(ChannelMediaRelayConfiguration channelMediaRelayConfiguration) {
        //TODO: 没有
        return -1;
    }

    @Override
    public int startDumpVideoReceiveTrack(int i, String s) {
        return -1;
    }

    @Override
    public int stopDumpVideoReceiveTrack() {
        //TODO: 没有
        return -1;
    }

    @Override
    public RtcChannel createRtcChannel(String s) {
        return null;
    }

    @Override
    public int getAudioMixingDuration() {
        if (mIsLeaved) {
            Log.e("qtt_mixer", "get audio mix duration failed as not join channel");
            return -1;
        }
        return rtcEngine.getSoundDuration();
    }

    @Override
    public int getAudioMixingCurrentPosition() {
        if (mIsLeaved) {
            Log.e("qtt_mixer", "get audio mix pos failed as not join channel");
            return -1;
        }
        return rtcEngine.getSoundPosition();
    }

    @Override
    public int setAudioMixingPosition(int pos) {
        if (mIsLeaved) {
            Log.e("qtt_mixer", "set audio mix position failed as not join channel");
            return -1;
        }
        return rtcEngine.setSoundPosition(pos);
    }

    @Override
    public int setAudioMixingPitch(int i) {
        if (mIsLeaved) {
            Log.e("qtt_mixer", "set audio mix pitch failed as not join channel");
            return -1;
        }
        return rtcEngine.setSoundPitch(i);
    }

    @Override
    public IAudioEffectManager getAudioEffectManager() {
        //TODO: 没有
        return null;
    }

    /**
     * @param filePath
     * @param quality
     * @deprecated
     */
    @Override
    public int startAudioRecording(String filePath, int quality) {
        //todo quality
        rtcEngine.startRecord(filePath);
        return 0;
    }

    @Override
    public int startAudioRecording(String filePath, int sampleRate, int quality) {
        //todo quality sampleRate
        rtcEngine.startRecord(filePath);
        return 0;
    }

    @Override
    public int stopAudioRecording() {
        rtcEngine.stopRecord();
        return 0;
    }

    /**
     * @deprecated
     */
    @Override
    public int startEchoTest() {
        return 0;
    }

    @Override
    public int startEchoTest(int intervalInSeconds) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int stopEchoTest() {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int enableLastmileTest() {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int disableLastmileTest() {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int startLastmileProbeTest(LastmileProbeConfig config) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int stopLastmileProbeTest() {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int setVideoSource(IVideoSource source) {
        //TODO: 暂时没有
        return -1;
    }

    @Override
    public int pauseAudioMixing() {
        return rtcEngine.pauseSound();
    }

    @Override
    public int resumeAudioMixing() {
        return rtcEngine.resumeSound();
    }

    public ChannelEngine getQttInstance() {
        return rtcEngine;
    }

    public void changeMicProfile(int val) {
//        if (val == MicProfile.CHAT_MIC_PROFILE.value())
//            rtcEngine.changeMicProfile(MicProfile.CHAT_MIC_PROFILE);
//        else if (val == MicProfile.MUSIC_MIC_PROFILE.value())
//            rtcEngine.changeMicProfile(MicProfile.MUSIC_MIC_PROFILE);
//        else if (val == MicProfile.MUSIC_PRO_MIC_PROFILE.value())
//            rtcEngine.changeMicProfile(MicProfile.MUSIC_PRO_MIC_PROFILE);
    }


    //Todo 下面的都没有，就没有一个个写注释了


    @Override
    public int setLocalVideoRenderer(IVideoSink render) {
        return 0;
    }

    @Override
    public int setRemoteVideoRenderer(int uid, IVideoSink render) {
        return 0;
    }

    @Override
    public int setExternalAudioSink(boolean enabled, int sampleRate, int channels) {
        return 0;
    }

    @Override
    public int pullPlaybackAudioFrame(byte[] data, int lengthInByte) {
        return 0;
    }

    @Override
    public int setExternalAudioSource(boolean enabled, int sampleRate, int channels) {
        return 0;
    }

    @Override
    public int pushExternalAudioFrame(byte[] data, long timestamp) {
        return 0;
    }

    @Override
    public void setExternalVideoSource(boolean enable, boolean useTexture, boolean pushMode) {

    }

    @Override
    public boolean pushExternalVideoFrame(AgoraVideoFrame frame) {
        return false;
    }

    @Override
    public boolean isTextureEncodeSupported() {
        return false;
    }

    @Override
    public int registerAudioFrameObserver(IAudioFrameObserver observer) {
        return 0;
    }

    @Override
    public int setRecordingAudioFrameParameters(int sampleRate, int channel, int mode, int samplesPerCall) {
        return 0;
    }

    @Override
    public int setPlaybackAudioFrameParameters(int sampleRate, int channel, int mode, int samplesPerCall) {
        return 0;
    }

    @Override
    public int setMixedAudioFrameParameters(int sampleRate, int samplesPerCall) {
        return 0;
    }

    /**
     * @param watermark
     * @deprecated
     */
    @Override
    public int addVideoWatermark(AgoraImage watermark) {
        return 0;
    }

    @Override
    public int addVideoWatermark(String watermarkUrl, WatermarkOptions options) {
        return 0;
    }

    @Override
    public int clearVideoWatermarks() {
        return 0;
    }

    @Override
    public int setRemoteUserPriority(int uid, int userPriority) {
        return 0;
    }

    @Override
    public int setLocalPublishFallbackOption(int option) {
        return 0;
    }

    @Override
    public int setRemoteSubscribeFallbackOption(int option) {
        return 0;
    }

    @Override
    public int enableDualStreamMode(boolean enabled) {
        return 0;
    }

    @Override
    public int setRemoteVideoStreamType(int uid, int streamType) {
        return 0;
    }

    @Override
    public int setRemoteDefaultVideoStreamType(int streamType) {
        return 0;
    }

    @Override
    public int setEncryptionSecret(String secret) {
        return 0;
    }

    @Override
    public int setEncryptionMode(String encryptionMode) {
        return 0;
    }

    @Override
    public int enableEncryption(boolean enabled, EncryptionConfig config) {
        return 0;
    }

    @Override
    public int addInjectStreamUrl(String url, LiveInjectStreamConfig config) {
        return 0;
    }

    @Override
    public int removeInjectStreamUrl(String url) {
        return 0;
    }

    @Override
    public int addPublishStreamUrl(String url, boolean transcodingEnabled) {
        return 0;
    }

    @Override
    public int removePublishStreamUrl(String url) {
        return 0;
    }

    @Override
    public int setLiveTranscoding(LiveTranscoding transcoding) {
        return 0;
    }

    @Override
    public int createDataStream(boolean reliable, boolean ordered) {
        return 0;
    }

    @Override
    public int sendStreamMessage(int streamId, byte[] message) {
        return 0;
    }

    /**
     * @param preferFrameRateOverImageQuality
     * @deprecated
     */
    @Override
    public int setVideoQualityParameters(boolean preferFrameRateOverImageQuality) {
        return 0;
    }

    @Override
    public int setLocalVideoMirrorMode(int mode) {
        return 0;
    }

    @Override
    public int switchCamera() {
        return 0;
    }

    @Override
    public boolean isCameraZoomSupported() {
        return false;
    }

    @Override
    public boolean isCameraTorchSupported() {
        return false;
    }

    @Override
    public boolean isCameraFocusSupported() {
        return false;
    }

    @Override
    public boolean isCameraExposurePositionSupported() {
        return false;
    }

    @Override
    public boolean isCameraAutoFocusFaceModeSupported() {
        return false;
    }

    @Override
    public int setCameraZoomFactor(float factor) {
        return 0;
    }

    @Override
    public float getCameraMaxZoomFactor() {
        return 0;
    }

    @Override
    public int setCameraFocusPositionInPreview(float positionX, float positionY) {
        return 0;
    }

    @Override
    public int setCameraExposurePosition(float positionXinView, float positionYinView) {
        return 0;
    }

    @Override
    public int enableFaceDetection(boolean b) {
        return -1;
    }

    @Override
    public int setCameraTorchOn(boolean isOn) {
        return 0;
    }

    @Override
    public int setCameraAutoFocusFaceModeEnabled(boolean enabled) {
        return 0;
    }

    @Override
    public String getCallId() {
        return null;
    }

    @Override
    public int rate(String callId, int rating, String description) {
        return 0;
    }

    @Override
    public int complain(String callId, String description) {
        return 0;
    }


}
